package model

import (
	"github.com/lab-online/internal/class/entity"
	"github.com/lab-online/pkg/model"
	"github.com/lab-online/pkg/util"
)

type Class struct {
	model.BaseModel
	Name        string    `gorm:"type:varchar(100);not null"`
	Description string    `gorm:"type:text;not null"`
	CourseID    uint      `gorm:"not null"`
	Teacher     string    `gorm:"type:varchar(10);not null"`
	Students    []Student `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL"`
}

func (c *Class) ToEntity() entity.ClassEntity {
	classEntity := &entity.Class{
		Name:        c.Name,
		CourseID:    c.CourseID,
		Description: c.Description,
	}
	entity.AddStudents()
	classEntity.UpdateEntity(
		entity.WithID(c.ID),
		entity.WithTeacher(c.Teacher),
		entity.WithStudents(util.SliceMap(c.Students, func(student Student) string {
			return student.Username
		})...),
	)

	return classEntity
}

type ClassOption func(*Class)

func New(opts ...ClassOption) *Class {
	class := &Class{}
	for _, opt := range opts {
		opt(class)
	}

	return class
}

func WithID(id uint) ClassOption {
	return func(c *Class) {
		c.ID = id
	}
}

func WitchCourseID(courseID uint) ClassOption {
	return func(c *Class) {
		c.CourseID = courseID
	}
}

func WithTeacher(teacher string) ClassOption {
	return func(c *Class) {
		c.Teacher = teacher
	}
}

func WithEntity(class entity.ClassEntity) ClassOption {
	return func(c *Class) {
		c.ID = class.GetID()
		c.Name = class.GetName()
		c.Teacher = class.GetTeacher()
		c.CourseID = class.GetCourseID()
		c.Description = class.GetDescription()
		c.Students = util.SliceMap(class.GetStudents(), func(student string) Student {
			return Student{class.GetID(), student}
		})

	}
}
